package com.protocol;

/**
 * @author linyu.dai
 * @project rpc
 * @description http请求参数解析器
 * @creat 2022/11/30 09:55:58
 */

import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HTTP请求参数解析器, 支持GET, POST
 * Created by whf on 12/23/15.
 */
@Slf4j
public class RequestParser {
    private FullHttpRequest fullReq;

    /**
     * 构造一个解析器
     * @param req
     */
    public RequestParser(FullHttpRequest req) {
        this.fullReq = req;
    }

    /**
     * 解析请求参数
     * @return 包含所有请求参数的键值对, 如果没有参数, 则返回空Map
     * @throws IOException
     */
    public Map<String, String> parse() throws IOException {
        HttpMethod method = fullReq.method();

        Map<String, String> paramMap = new HashMap<>();

        if (fullReq.headers().get("Content-Type")==null || HttpMethod.GET == method) {
            // 是GET请求
            QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri());
            decoder.parameters().forEach((key, value) -> {
                // entry.getValue()是一个List, 只取第一个元素
                paramMap.put(key, value.get(0));
            });
        } else if (HttpMethod.POST == method) {
            // 是POST请求
            switch (fullReq.headers().get("Content-Type")){
                case "application/x-www-form-urlencoded":
                    HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullReq);
                    decoder.offer(fullReq);
                    List<InterfaceHttpData> paramList = decoder.getBodyHttpDatas();
                    for (InterfaceHttpData param : paramList) {
                        Attribute data = (Attribute) param;
                        paramMap.put(data.getName(), data.getValue());
                    }
                    break;
                case "application/json":{
                    ByteBuf byteBuf = fullReq.content();
                    byte[] bytes = new byte[byteBuf.readableBytes()];
                    byteBuf.readBytes(bytes, 0, byteBuf.readableBytes());
                    String content = new String(bytes, StandardCharsets.UTF_8);
                    paramMap.put("jsonData", content);
//                    log.info("内容{}", content);
                }
                default:
                    break;
            }
        } else {
            // 不支持其它方法
            throw new RuntimeException("不支持其他方法"); // 这是个自定义的异常, 可删掉这一行
        }
        return paramMap;
    }
}
